/* ** por compatibilidad se omiten tildes **
================================================================================
 TRABAJO PRACTICO 3 - System Programming - ORGANIZACION DE COMPUTADOR II - FCEN
================================================================================
  definicion de estructuras para administrar tareas
*/

#include "tss.h"
#include "mmu.h"
#include "sched.h"

tss tss_next_1;
tss tss_next_2;

tss tss_inicial;
tss tss_idle;

tss sched[9];
tss tss_tanques[CANT_TANQUES];

void tss_inicializar() {

	/*info de la tarea inicial en la  gdt */	
	//inicializar_tareas();	
	unsigned int asd   = (unsigned int) &tss_inicial;
	gdt[14].base_0_15  = (unsigned short)asd;
	gdt[14].base_23_16 =  (unsigned char)(asd>>16);
	gdt[14].base_31_24 = (unsigned char)(asd>>24);

	/*Ejercicio 6 b)*/
	/*TSS1: Información de la tarea Idle */	
	tss_idle.eflags = 0x00000202;	//Valor hardcodeado
	tss_idle.cr3 = 0x27000; 	//Comparte el cr3 con el kernel
	tss_idle.eip = 0x20000;		//Ubicación de la tarea
	tss_idle.esp = 0x26ffc; 	//La pila de esta tarea es la misma que la del kernel
	tss_idle.ebp = 0x26ffc; 	//Idem
	tss_idle.es  = 11<<3;
	tss_idle.ss  = 11<<3;
	tss_idle.ds  = 11<<3;
	tss_idle.gs  = 11<<3;
	tss_idle.cs  = 9<<3;
	tss_idle.fs  = 13<<3;
	tss_idle.ldt = 0;		//Valor hardcodeado
	tss_idle.iomap = 0xFFFF;	//Valor hardcodeado

	/*posición base de la tarea para llenar la entry de la GDT de la tarea Idle */
        tss_copy(&tss_idle, &tss_next_1);	
	asd = (unsigned int) &tss_next_1;
	gdt[15].base_0_15 = (unsigned short)  asd;
	gdt[15].base_23_16 =  (unsigned char) (asd>>16);
	gdt[15].base_31_24 = (unsigned char)  (asd>>24);

	/*Ejercicio 6 c), información de los tanques */
	unsigned int i = 0;
	for (i = 0; i < CANT_TANQUES; i++) {

		tss_tanques[i].cr3 = cr3s[i]; 				//el cr3 correspondiente al tanque iésimo
		tss_tanques[i].eip = 0x8000000;
		tss_tanques[i].eflags = 0x0000202; 			//Valor hardcodeado
		tss_tanques[i].esp = 0x8002000 - 4;
		tss_tanques[i].ebp = 0x8002000 - 4;

		tss_tanques[i].eax = 0;
		tss_tanques[i].ecx = 0;
		tss_tanques[i].edx = 0;
		tss_tanques[i].ebx = 0;
		tss_tanques[i].esi = 0;
		tss_tanques[i].edi = 0;

		tss_tanques[i].ss = (12<<3)+3;
		tss_tanques[i].ds = (12<<3)+3;
		tss_tanques[i].cs = (10<<3)+3;
		tss_tanques[i].fs = (12<<3)+3;
		tss_tanques[i].es = (12<<3)+3;
		tss_tanques[i].gs = (12<<3)+3;

		tss_tanques[i].ldt = 0;
		tss_tanques[i].iomap = 0xFFFF; 				//Valor hardcodeado
		tss_tanques[i].esp0 = dame_memoria() + 0x1000;	//Pagina pedida para alojar la pila nivel 0
		tss_tanques[i].ss0 = (11<<3); // 					//Selector de segmento para datos nivel 0
	}
	/*Ejercicio 6 f), completar la entry en la gdt de la TSS2 */

	asd = (unsigned int) &tss_next_2;
	gdt[16].base_0_15 = (unsigned short) asd;
	gdt[16].base_23_16 = (unsigned char) (asd>>16);
	gdt[16].base_31_24 = (unsigned char) (asd>>24);

}

void tss_copy(tss* tss_src, tss* tss_dst){

	*tss_dst = *tss_src;
}
